﻿using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using TransformerManager.Shared.Helper.HttpParams;
using TransformerManager.WPF.Common.Utils;
using hc = HandyControl.Controls;

namespace TransformerManager.WPF.Common.Http
{
    public class HttpRequest
    {
        private readonly HttpClient _httpClient;
        private string _local_ip = string.Empty;

        public HttpRequest(HttpClient client)
        {
            _httpClient = client;
        }

        public async Task<ResponseParams> RequestAsync(
            HttpMethod httpMethod,
            string url,
            Dictionary<string, string> headers,
            string reqBody = "")
        {
            int statusCode;

            try
            {
                Uri reqUri = new Uri(_httpClient.BaseAddress.ToString() + url);

                HttpRequestMessage requestMessage = new HttpRequestMessage(httpMethod, reqUri);

                if(httpMethod != HttpMethod.Get)
                {
                    StringContent stringContent = new StringContent(
                        reqBody,
                        Encoding.UTF8,
                        "application/json"
                        );
                    requestMessage.Content = stringContent;
                }    

                requestMessage.Headers.Add("Connection", "keep-alive");
                requestMessage.Headers.Add("Authorization", $"Bearer {AccountInfo.JwtToken}");

                // 从主机的IPV4中任意选一个IP进行记录
                if (string.IsNullOrEmpty(_local_ip))
                {
                    var ipadrs = Dns.GetHostAddresses(Dns.GetHostName());
                    foreach (var ipadr in ipadrs)
                    {
                        if (ipadr.AddressFamily == AddressFamily.InterNetwork)
                        {
                            _local_ip = ipadr.ToString();
                            break;
                        }
                        _local_ip = "NULL";
                    }
                }
                requestMessage.Headers.Add("remote_addr", _local_ip);

                if (headers != null)
                {
                    foreach (var item in headers)
                    {
                        requestMessage.Headers.Add(item.Key, item.Value);
                    }
                }

                // 请求响应
                var response = await _httpClient.SendAsync(requestMessage);
                statusCode = (int)response.StatusCode;
                // 响应内容
                var responseContent = await response.Content.ReadAsStringAsync();
                var responseHeaders = response.Headers;
                // 反序列化
                var responseContentJson = JsonConvert.DeserializeObject<ApiResponseParams>(responseContent);

                // 响应本体可能为空需要处理
                string message = responseContentJson == null ? string.Empty : responseContentJson.Message.ToString();

                var statusCodeMsg = GetStatusCodeDescription((HttpStatusCode)statusCode);

                // 请求成功
                if (statusCode.ToString().StartsWith("2"))
                {
                    if (!string.IsNullOrEmpty(message))
                    {
                        hc.Growl.Success($"响应信息：{message}", "Notification");
                    }
                    return new ResponseParams
                    {
                        Result = responseContentJson.Result,
                        Headers = responseHeaders,
                        Message = message
                    };
                }
                else if(statusCode == 422)
                {
                    if (string.IsNullOrEmpty(message)) message = "无响应内容";
                    hc.Growl.Error(
                        $"状态码: {statusCode}, 状态码信息: {statusCodeMsg} 响应信息: {responseContentJson.Result}。",
                        "Notification");
                    return null;
                }
                // 请求失败
                else
                {
                    if (string.IsNullOrEmpty(message)) message = "无响应内容";
                    hc.Growl.Error(
                        $"状态码: {statusCode}, 状态码信息: {statusCodeMsg} 响应信息: {message}。", 
                        "Notification");

                    return null;
                }

            }
            catch (Exception e)
            {
                hc.MessageBox.Show(
                    $"异常信息:{e.Message}",
                    "错误",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
               return null;
            }
        }

        private string GetStatusCodeDescription(HttpStatusCode httpStatusCode)
        {
            string msg = httpStatusCode switch
            {
                // 20X
                HttpStatusCode.OK => "请求成功!",
                HttpStatusCode.Created => "请求已被实现!",
                HttpStatusCode.Accepted => "服务器已成功处理了请求,但返回了可能来自另一来源的信息!",
                HttpStatusCode.NoContent => "服务器已处理用户的请求数据,无返回数据!",
                HttpStatusCode.ResetContent => "服务器成功处理了请求，但未返回任何内容,需要用户重置文档视图!",
                HttpStatusCode.PartialContent => "服务器成功处理了部分 GET 请求!",
                // 30X
                HttpStatusCode.MultipleChoices => "用户需要重定向链接!",
                HttpStatusCode.MovedPermanently => "被请求的资源已永久移动到新位置!请用户转向新链接!",
                HttpStatusCode.Found => "原始请求方法是 POST, 重定向的请求将使用 GET 方法!",
                HttpStatusCode.RedirectMethod => "客户端将自动重定向到的另一个URL,需采用GET请求!",
                HttpStatusCode.NotModified => "自上次请求后，请求的网页未被修改过",
                HttpStatusCode.UseProxy => "需在header中增加代理来访问请求链接!",
                // 40X
                HttpStatusCode.BadRequest => "语义有误，当前请求无法被服务器理解!请核查请求内容是否符合规范!",
                HttpStatusCode.Unauthorized => "请求用户未被授权!",
                HttpStatusCode.Forbidden => "禁止用户访问该资源!",
                HttpStatusCode.NotFound => "请求失败,未检索到请求资源!",
                HttpStatusCode.MethodNotAllowed => "该请求方法不被允许!",
                HttpStatusCode.NotAcceptable => "无法使用请求的内容特性响应请求的网页!",
                HttpStatusCode.ProxyAuthenticationRequired => "请求用户需要在代理服务器上完成身份验证!",
                HttpStatusCode.RequestTimeout => "请求超时!",
                HttpStatusCode.Conflict => "请求发生冲突!",
                HttpStatusCode.UnprocessableEntity => "传递参数不符合规范!",
                // 50X
                HttpStatusCode.InternalServerError => "服务器内部错误!",
                HttpStatusCode.NotImplemented => "服务器不支持所请求的功能!",
                HttpStatusCode.BadGateway => "错误网关!",
                HttpStatusCode.ServiceUnavailable => "服务器暂时不可用!",
                HttpStatusCode.GatewayTimeout => "网关超时!",
                HttpStatusCode.HttpVersionNotSupported => "HTTP 版本不受支持!服务器不支持请求中所使用的 HTTP 协议版本!",
                HttpStatusCode.Continue => throw new NotImplementedException(),
                HttpStatusCode.SwitchingProtocols => throw new NotImplementedException(),
                HttpStatusCode.Processing => throw new NotImplementedException(),
                HttpStatusCode.EarlyHints => throw new NotImplementedException(),
                HttpStatusCode.NonAuthoritativeInformation => throw new NotImplementedException(),
                HttpStatusCode.MultiStatus => throw new NotImplementedException(),
                HttpStatusCode.AlreadyReported => throw new NotImplementedException(),
                HttpStatusCode.IMUsed => throw new NotImplementedException(),
                HttpStatusCode.Unused => throw new NotImplementedException(),
                HttpStatusCode.RedirectKeepVerb => throw new NotImplementedException(),
                HttpStatusCode.PermanentRedirect => throw new NotImplementedException(),
                HttpStatusCode.PaymentRequired => throw new NotImplementedException(),
                HttpStatusCode.Gone => throw new NotImplementedException(),
                HttpStatusCode.LengthRequired => throw new NotImplementedException(),
                HttpStatusCode.PreconditionFailed => throw new NotImplementedException(),
                HttpStatusCode.RequestEntityTooLarge => throw new NotImplementedException(),
                HttpStatusCode.RequestUriTooLong => throw new NotImplementedException(),
                HttpStatusCode.UnsupportedMediaType => throw new NotImplementedException(),
                HttpStatusCode.RequestedRangeNotSatisfiable => throw new NotImplementedException(),
                HttpStatusCode.ExpectationFailed => throw new NotImplementedException(),
                HttpStatusCode.MisdirectedRequest => throw new NotImplementedException(),
                HttpStatusCode.Locked => throw new NotImplementedException(),
                HttpStatusCode.FailedDependency => throw new NotImplementedException(),
                HttpStatusCode.UpgradeRequired => throw new NotImplementedException(),
                HttpStatusCode.PreconditionRequired => throw new NotImplementedException(),
                HttpStatusCode.TooManyRequests => throw new NotImplementedException(),
                HttpStatusCode.RequestHeaderFieldsTooLarge => throw new NotImplementedException(),
                HttpStatusCode.UnavailableForLegalReasons => throw new NotImplementedException(),
                HttpStatusCode.VariantAlsoNegotiates => throw new NotImplementedException(),
                HttpStatusCode.InsufficientStorage => throw new NotImplementedException(),
                HttpStatusCode.LoopDetected => throw new NotImplementedException(),
                HttpStatusCode.NotExtended => throw new NotImplementedException(),
                HttpStatusCode.NetworkAuthenticationRequired => throw new NotImplementedException(),
                _ => "异常信息,请联系管理员处理!",
            };
            return msg;
        }
    }
}
